<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<input type = "text">
<script>
    /*
    * 节流和防抖：
    *   提升性能减小浪费
    *
    * 防抖操作业务需求：常用于关键词搜索 dom操作渲染(用户移动滚轮，移动到最后停止时才进行渲染)
    *   在input中输入内容的时候会向后台发送请求，返回列表，进行渲染等等操作
    *   .oninput 输入事件 在被输入的时候 和.onclick类似
    *   在输入框输入一段内容，会很快速地执行每一次输入函数，然鹅我们只有最后一次输入是我们需要的结果，前面的都过滤掉，通过标记用户输入停止支付才发送请求
    *   多次高频操作，前面的都忽略，只保留最后一次结果
    *
    * 防抖操作优点：减小请求数，减小dom操作频率，提升性能
    *
    * */

    let input = document.querySelector("input")

    //input.oninput = function(){ //给oninput事件绑定的回调函数
    //    console.log(this.value) //回调函数是绑定在oninput事件上面的，oninput是被input调用的，所以这里面的this指向input
    //} //这个函数会每次输入后都进行打印输入值，不符合节流防抖

    /*
    * 分析输入行为：
    *   在输入框输入一段内容，会很快速地执行每一次输入函数，然鹅我们只有最后一次输入是我们需要的结果，也就是说最后一次是有效输入，其他都是不需要的
    *   如何将前面不需要的结果过滤掉，需要设置一个延时定时器和在规定内清除上次延时定时器，比如要一次性输入123，可以下面这样写
    *
    * */
    let timer = null //提前声明一个timer 使其默认值值为null

    //防抖操作
    input.oninput = function (){ //父级函数是回调函数，被绑定到oninput上，被input调用，所以父级函数this指向input
        clearTimeout(timer) //每一次oninput输入事件函数执行，都会提前把上一次的timer清除掉
        //设置一个延时定时器 赋值给timer 这样如果在一秒内再进行下一次oninput输入事件函数执行时，清除的延时定时器就是这一次的延时定时器
        //因为我们设定的延时定时器是一秒钟之后再执行打印内容，如果在一秒钟内我们清除了这次的延时定时器，那么上一次的内容就不会打印
        //而是重新又生成一个延时定时器，规定一秒钟之后打印这次输入的内容
        timer = setTimeout(() => { //箭头函数的this指向被绑定到父级函数的this
            //下面的打印输入值这一行代码是防抖操作中自己需要写的代码，即进行什么样的操作，进行打印输入值的操作
            console.log(this.value) //箭头函数强行绑定上下文，this也指向input
        },1000) //一秒钟后打印输出的内容
    }

    /* 以下是上面这个函数执行输入打印123的过程
    * 1.例如一次性输入123，第一次输入1时，oninput输入事件函数执行，里面的清除延时定时器clearTimeout执行，清除了在全局设定的值为null的timer，
    *   将timer的值赋值为延时定时器setTimeout执行之后的值1，但是设定了一秒钟之后才打印出值1，
    * 2.如果我们在这一秒钟之内接着输入2，oninput输入事件函数又执行，里面的清除延时定时器clearTimeout也执行，
    *   清除了timer值等于第一次生成的延时定时器设定的一秒后打印输入的值1，改成了timer值为这一次生成延时定时器执行之后的值12，设定了在新的一秒后才打印输入值12，
    * 3.如果我们又在新的一秒之内接着输入3，oninput输入事件函数再次执行，里面的清除延时定时器clearTimeout也再次执行，
    *   清除了timer值等于第二次生成的延时定时器设定的一秒后打印的输入值12，改成了timer值为这一次生成延时定时器执行之后的值123，
    *   设定了在新的一秒后才打印输入的值123，然后最后这一次我们已经完成输入了，一秒钟之后，最新的延时定时器执行，打印最后输入的值123
    * */

</script>
</body>
</html>